package impl

import (
	"context"
	"go_restful_api/pkg/host"
)

func (s *service) Save(ctx context.Context, host *host.Host) error {
	var (
		err error
	)

	// 开启一个事务
	tx, err := s.db.BeginTx(ctx, nil)
	if err != nil {
		return err
	}

	// 执行结果提交或者回滚事务
	// 当使用 sql.Tx 的操作方式操作数据后，需要我们使用 sql.Tx 的 commit() 方法显示的提交事务
	// 如果出错，则可以使用 sql.Tx 中的 Rollback() 方法回滚事务，保持数据一致性
	defer func() {
		if err != nil {
			tx.Rollback()
			return
		}
	}()

	// 先保存Resource避免SQL注入，请使用Prepare
	sourceStmt, err := tx.Prepare(insertResourceSQL)
	if err != nil {
		return err
	}
	defer sourceStmt.Close()

	// id, vendor, region, create_at, expire_at, type, name, description, status, update_at, sync_at,account, public_ip, private_ip
	_, err = sourceStmt.Exec(host.Id, host.Vendor, host.Region, host.CreateAt, host.ExpireAt, host.Type, host.Name, host.Description, host.Status, host.UpdateAt, host.SyncAt, host.SyncAccount, host.PublicIP, host.PrivateIP)
	if err != nil {
		return err
	}

	// 保存Host表
	hostStmt, err := tx.Prepare(insertHostSQL)
	if err != nil {
		return err
	}
	defer hostStmt.Close()
	// resource_id, cpu, memory, gpu_amount, gpu_spec, os_type, os_name, serial_number
	_, err = hostStmt.Exec(host.ResourceId, host.CPU, host.Memory, host.GPUAmount, host.GPUSpec, host.OSType, host.OSName, host.SerialNumber)
	if err != nil {
		return err
	}
	tx.Commit()
	return nil
}
